package com.whosly.mysql.protocol.packet.impl;

import com.whosly.mysql.protocol.jdbc.MySQLMessage;
import com.whosly.mysql.protocol.packet.util.NettyBufferUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * <pre>
 *   Bytes                        Name
 *   -----                        ----
 *   1                            command
 *   n                            arg
 * </pre>
 *
 * @author fengyang(yueny09 @ 163.com)
 */
@Slf4j
public class NettyCommandPacket extends CommandPacket
{

    /**
     * The text of the command is just the way the user typed it, there is no processing
     * by the client (except removal of the final ';').
     * This field is not a null-terminated string; however,
     * the size can be calculated from the packet size,
     * and the MySQL client appends '/0' when receiving.
     */
    @Getter
    @Setter
    private byte[] arg;

    @Override
    public void read(byte[] bodyBytes) {
        readBody(bodyBytes);
    }

    @Override
    protected void readBody(byte[] bodyBytes) {
        MySQLMessage mm = new MySQLMessage(bodyBytes);

        setCmd(mm.read());

        int argLength = getPacketLength() - 1;
        setArg(mm.readBytes(argLength));
    }

    @Override
    public ByteBuf writeBuf(ByteBuf buffer)
    {
        NettyBufferUtil.writeUB3(buffer, buffer.capacity());
        buffer.writeByte(getPackId());

        writeBody(buffer);

        return buffer;
    }

    public void write(ChannelHandlerContext ctx) {
        int size = calcPacketSize();
        // default init 256,so it can avoid buff extract
        ByteBuf buffer = ctx.alloc().buffer(size);
        NettyBufferUtil.writeUB3(buffer, size);
        buffer.writeByte(getPackId());

        writeBody(buffer);

        ctx.writeAndFlush(buffer);
    }

    protected void writeBody(ByteBuf buffer) {
        buffer.writeByte(getCmd());
        buffer.writeBytes(getArg());

        try{
            String val = new String(getArg(), "utf-8");
            log.debug("COMMAND PACKET:{}.", val);
        }catch (Exception e){
            //.
        }
    }

    /**
     * 取得数据包信息
     */
    @Override
    public String getPacketInfo() {
        return "MySQL NettyCommand Packet";
    }
}
